#!/usr/bin/perl
my $Version;
use warnings;
use strict;

#    Config Migration Tool for Pete's Automated VGAP Hosting Thingy
#    Copyright (C) 1997-2004 Peter Harris
$    Version = '0.4.0';
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 2 as
#    published by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#    This program is currently hosted at http://www.agamemnon.net/vgap/

# Currently supports files as far back as 0.2.0. If you have an earlier
# file (highly unlikely), you'll have to migrate it by hand.

use Config::IniFiles;
use Digest::SHA1 'sha1_base64';
use Cwd;

our $ininame;
our $mainini;
our ($NumberOfGames,@ini);

sub GetSalt {
   my $game = shift;
   my $salt = $ini[$game]->val('General','Salt');
   if (!defined($salt)) {
      $salt = '';
      $salt .= ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64] foreach(1..8);
      $ini[$game]->newval('General','Salt',$salt);
   }
   return $salt;
}

sub GenerateCookie {
   my $game = shift;
   my $type = shift;
   my $email = shift;
   my $salt = GetSalt($game);

   return sha1_base64($salt, $type, $email);

   # A crypt based implementation would probably want to
   # use <the first letter of $type>.$email , $salt
   # And then trim the first two letters (the salt) from
   # the front of the digest before returning it.
}

sub HashPassword($$) {
   my $game = shift;
   my $pass = shift;

   defined($game) or return sha1_base64('SysadminPasswordSalt','Password',$pass);

   return GenerateCookie($game, 'Password', $pass);
}

sub IniLoad {
   -e $ininame or die ("Can't open $ininame.\n");

   $mainini = new Config::IniFiles( -file => $ininame ) or die("Cannot open $ininame because:\n$!\n");

   $NumberOfGames= $mainini->val('General','NumberOfGames');
   return unless ($NumberOfGames >= 1);

   foreach my $game (1..$NumberOfGames) {
      my $gameini= $mainini->val('GameINI',"Game$game");
      $ini[$game]=new Config::IniFiles( -file => $gameini ) or die("Cannot open $gameini\n");
   }
}

sub confirm($$$$)
{
   my $ini = shift;
   my $sec = shift;
   my $entry = shift;
   my $default = shift;

   my $val;

   $val = $ini->val($sec, $entry, $default);
   $ini->newval($sec, $entry, $val);
}

sub UpdatePasswords($)
{
   my $game = shift;
   my $ini = $ini[$game];
   my $password;

   foreach my $player (1..11)
   {
      $password = $ini->val("Player$player", 'Password');
      if (length($password) != 27 && $password ne 'None:None') {
         $password = HashPassword($game, $password);
      }
      $ini->setval("Player$player", 'Password', $password);
   }

   $password = $ini->val('Admin', 'Password');
   if (length($password) != 27 && $password ne 'None:None') {
      $password = HashPassword($game, $password);
   }
   $ini->setval('Admin', 'Password', $password);
}

$ininame = 'vgapd.ini';
$ininame = shift(@ARGV) if ($ARGV[0]);

my $password;

IniLoad;

print "Migrating $ininame...";
confirm($mainini, 'General','IniWriteMode','600');
confirm($mainini, 'General','Plugins','/usr/local/vgapd/commands');
confirm($mainini, 'Hooks','PreRun','');
confirm($mainini, 'Hooks','PostRun','');
confirm($mainini, 'Hooks','PostMail','');
$password = $mainini->val('General', 'SysadminPW');
if (length($password) != 27 && $password ne 'None:None') {
   $password = HashPassword(undef, $password);
}
$mainini->setval('General', 'SysadminPW', $password);

$mainini->RewriteConfig() or print " Error: Cannot write file.";

foreach my $game (1..$NumberOfGames)
{
   my $ininame = $mainini->val('GameINI',"Game$game");
   print " Done.\nMigrating $ininame...";

   confirm($ini[$game], 'Admin','TellMeAboutJoins','NO');
   confirm($ini[$game], 'Hooks','PreRun','');
   confirm($ini[$game], 'Hooks','PostRun','');
   confirm($ini[$game], 'Hooks','PostMail','');

   for my $player (1..11)
   {
      confirm($ini[$game], "Player$player", 'Compress', 'none');
      confirm($ini[$game], "Player$player", 'RenameXY', 'YES');
      confirm($ini[$game], "Player$player", 'AlliedFrom', '0');
   }
   UpdatePasswords($game);

   $ini[$game]->RewriteConfig() or print " Error: Cannot write file.";
}

print " Done.\n";
